package kz.kstu.scantest.desktop.ui.dialog;

import kz.kstu.scantest.app.delegate.api.AccountDelegate;
import kz.kstu.scantest.app.delegate.impl.AccountDelegateImpl;
import kz.kstu.scantest.business.common.exception.LoginFailedException;
import kz.kstu.scantest.business.entity.security.Account;
import kz.kstu.scantest.business.util.DigestUtil;
import kz.kstu.scantest.business.util.StringUtil;
import kz.kstu.scantest.desktop.util.GUIUtils;
import org.apache.log4j.Logger;

import javax.security.auth.login.LoginException;
import javax.swing.*;
import java.awt.event.*;
import java.security.NoSuchAlgorithmException;

public class ChangePasswordDialog extends JDialog {

    public static final Logger LOGGER = Logger.getLogger(LoginDialog.class);

    private static final String LOGIN_TITLE = "Авторизация";

    private static final int WIDTH = 400;
    private static final int HEIGHT = 200;
    private static final String NON_EQUALS_PASSWORDS = "Введенные пароли не совпадают";
    private static final String EMPTY_PASSWORD = "Пароль не может быть пустым";
    private static final String PASSWORD_SUCCESSFULLY_CHANGED = "Пароль успешно изменен";
    private static final String INCORRECT_LOGIN_OR_PASSWORD = "Логин и/или пароль указан неверно";

    private JPanel contentPane;
    private JButton buttonOK;
    private JButton buttonCancel;
    private JTextField loginField;
    private JPasswordField oldPasswordField;
    private JPasswordField confirmNewPasswordField;
    private JPasswordField newPasswordField;

    public ChangePasswordDialog() {
    }

    public void changePassword() {
        initStaticComponents();
    }

    private void initStaticComponents() {
        setContentPane(contentPane);
        setModal(true);
        setResizable(false);
        setSize(WIDTH, HEIGHT);
        initListeners();
        getRootPane().setDefaultButton(buttonOK);
        GUIUtils.centerAndShow(this);
    }

    private void initListeners() {
        buttonOK.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onOk();
            }
        });

        buttonCancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        });

// call onCancel() when cross is clicked
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                onCancel();
            }
        });

// call onCancel() on ESCAPE
        contentPane.registerKeyboardAction(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        onCancel();
                    }
                }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    }

    private void onOk() {
        AccountDelegate accountDelegate = new AccountDelegateImpl();
        String oldPassword = new String(oldPasswordField.getPassword());
        try {
            String encryptedOldPassword = DigestUtil.digest(oldPassword, DigestUtil.ALGORITHM_SHA);
            Account account = accountDelegate.login(loginField.getText(), encryptedOldPassword);
            String newPassword = new String(newPasswordField.getPassword());
            String confirmNewPassword = new String(confirmNewPasswordField.getPassword());
            if (StringUtil.isEmptyString(newPassword) || StringUtil.isEmptyString(confirmNewPassword)) {
                shoMessage(EMPTY_PASSWORD, JOptionPane.ERROR_MESSAGE);
                return;
            }
            if (!newPassword.equals(confirmNewPassword)) {
                shoMessage(NON_EQUALS_PASSWORDS, JOptionPane.ERROR_MESSAGE);
                return;
            }
            String encryptedNewPassword = DigestUtil.digest(newPassword, DigestUtil.ALGORITHM_SHA);
            accountDelegate.changePassword(account.getId(), encryptedNewPassword);
            shoMessage(PASSWORD_SUCCESSFULLY_CHANGED, JOptionPane.INFORMATION_MESSAGE);
            dispose();
        } catch (LoginException e) {
            shoMessage(INCORRECT_LOGIN_OR_PASSWORD, JOptionPane.ERROR_MESSAGE);
        }
    }

    public void shoMessage(String message, int messageType) {
        JOptionPane.showMessageDialog(this, message, LOGIN_TITLE, messageType);
    }

    private void onCancel() {
// add your code here if necessary
        dispose();
    }
}
